package com.jiyongjun.component.exception.parser;

import com.jiyongjun.component.annotation.ApiMethodMetadata;
import com.jiyongjun.component.enums.LogConstant;
import com.jiyongjun.component.enums.LogResultTypeEnum;
import com.jiyongjun.component.exception.ServiceException;
import org.apache.dubbo.rpc.Invocation;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Optional;

/**
 * <h2></h2>
 * <h3>描述：</h3>
 *
 * @author yongjun.jyj
 * @since 2022/6/13 18:54
 */
@Component("defaultThrowableParser")
public class ThrowableParser implements ExceptionParser{
    @Override
    public boolean isMatch(Throwable throwable) {
        return true;
    }

    @Override
    public ExceptionParseResult handle(Invocation invocation, Throwable throwable) {
        ExceptionParseResult exceptionParseResult = new ExceptionParseResult();
        exceptionParseResult.setRaw(throwable);
        exceptionParseResult.setExceptionType(LogResultTypeEnum.SERVICE_EXCEPTION.getCode());
        exceptionParseResult.setMsgCode(LogConstant.DEFAULT_SERVICE_EXCEPTION_CODE);
        exceptionParseResult.setMsgInfo(LogConstant.DEFAULT_SERVICE_EXCEPTION_MESSAGE);

        Optional.ofNullable(invocation.getServiceModel())
                .flatMap(serviceModel -> Optional.ofNullable(serviceModel.getServiceModel().getMethod(invocation.getMethodName(), invocation.getParameterTypes())
                        .getMethod().getAnnotation(ApiMethodMetadata.class)))
                .ifPresent(apiMethodMetadata -> exceptionParseResult.setMsgInfo(apiMethodMetadata.serviceExceptionMsg()));

        return exceptionParseResult;
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }

}
